import abstract_factory.AbstractFactory;
import abstract_factory.AirConditioner;
import abstract_factory.CarNavigation;
import adapter.*;
import builder.*;
import factory_method.AudiFactory;
import factory_method.BenzFactory;
import factory_method.BmwFactory;
import observer.Client;
import observer.Server;
import proxy.Proxy;
import simple_factory.Bmw;
import simple_factory.Car;
import simple_factory.Factory;
import singleton.*;
import strategy.Context;
import strategy.Strategy;
import strategy.StrategyA;
import strategy.StrategyB;

public class Main {

    public static void main(String[] args) {

//        testSingleton();

//        testSimpleFactory();

//        testFactoryMethod();

//        testAbstractFactory();

//        testBuilder();

//        testAdapter();

//        testProxy();

//        testObserver();

//        testStrategy();
    }

    private static void testSimpleFactory(){
        Car car = Factory.productCar("Benz");
        car.drive();

        Car car1 = Factory.productCar("Bmw");
        car1.drive();
    }

    private static void testFactoryMethod(){
        Car benz = new BenzFactory().productCar();
        benz.drive();

        Car bmw = new BmwFactory().productCar();
        bmw.drive();

        Car audi = new AudiFactory().productCar();
        audi.drive();
    }

    private static void testAbstractFactory(){
        System.out.println("--------------BenzFactory----------------");

        AbstractFactory factory = new abstract_factory.BenzFactory();
        AirConditioner benzConditioner = factory.productAirConditioner();
        benzConditioner.refrigeration();
        CarNavigation benzNavigation = factory.productCarNavigation();
        benzNavigation.navigation();

        System.out.println("\n--------------BmwFactory----------------");

        AbstractFactory factory1 = new abstract_factory.BmwFactory();
        AirConditioner bmwConditioner = factory1.productAirConditioner();
        bmwConditioner.refrigeration();
        CarNavigation bmwNavigation = factory1.productCarNavigation();
        bmwNavigation.navigation();
    }

    private static void testSingleton(){
        Singleton1.getInstance();
        Singleton2.getInstance();
        Singleton3.getInstance();
        Singleton4.getInstance();
        Singleton5.INSTANCE.getName();
    }

    private static void testBuilder(){
        Director director = new Director();
        director.setBuilder(new BuilderA());
        Product product = director.construct();
        System.out.println(product.toString());

        director.setBuilder(new BuilderB());
        Product product1 = director.construct();
        System.out.println(product1.toString());

        // 链式写法
//        Product product2 = new BuilderC().buildPartA("鸡腿").buildPartB(99).buildPartC(20181207).getResult();
//        System.out.println(product2.toString());
    }

    private static void testAdapter(){

        // 类适配器
        DC5 classTarget = new ClassAdapter();
        classTarget.output5V();

        // 对象适配器
        DC5 objectTarget = new ObjectAdapter(new AC220());
        objectTarget.output5V();

        // 对象适配器
        DC5 target110 = new Adapter110(new AC110());
        target110.output5V();
    }

    private static void testProxy(){
        Proxy proxy = new Proxy();
        proxy.request();
    }

    private static void testObserver(){
        Server server = new Server();
        Client clientA = new Client("A");
        Client clientB = new Client("B");
        Client clientC = new Client("C");

        server.attach(clientA);
        server.attach(clientB);

        server.setMessage("1111111111");
        server.notifyToAll();

        server.detach(clientA);
        server.setMessage("2222222222");
        server.notifyToAll();
    }

    private static void testStrategy(){

        Context context = new Context();
        Strategy strategyA = new StrategyA();
        Strategy strategyB = new StrategyB();

        context.setStrategy(strategyA);
        context.algorithm();

        context.setStrategy(strategyB);
        context.algorithm();
    }

}
